<?php
/**
 * Created by PhpStorm.
 * User: yafex
 * Date: 2019/8/23
 * Time: 10:23
 */
class ctrl_codeGenerator extends L {

    /**
     * 描述：代码生成器页面展示
     * 作者：Zoro.Zhu
     **/
    public function index(){
        $schema = model_codeGenerator::getSchema();
        $this->view->schema = $schema;
        $this->view->headTitle = '代码生成器';
        $this->display('/html/codeGenerator.html');
    }

    /**
     * 描述：获取数据库的表名
     * 作者：Zoro.Zhu
     **/
    public function getFromName(){
        $schema = !empty($_POST['schema']) ? $_POST['schema'] : '';
        $fromName = model_codeGenerator::getFromName($schema);
        return array('state' => 200, 'info' => '获取成功', 'data' => $fromName);
    }

    /**
     * 描述：获取字段列的信息
     * 作者：Zoro.Zhu
     **/
    public function getColumnList(){
        $schema = !empty($_POST['schema']) ? $_POST['schema'] : '';
        $fromName = !empty($_POST['fromName']) ? $_POST['fromName'] : '';
        $columnList = model_codeGenerator::getColumnList($schema, $fromName);
        $tableName = model_codeGenerator::getTableComment($schema, $fromName);
        return array('state' => 200, 'info' => '获取成功', 'data' => $columnList, 'tableName' => $tableName);
    }

    /**
     * 描述：开始生成代码
     * 参数：{
     *      $_POST : {
     *
     *      }
     * }
     * 作者：Zoro.Zhu
     **/
    public function codeGenerator(){
        $_POST['fromNameNew'] = self::fromNameChange($_POST['fromName']);                                      //处理一下表名
        $_POST['keyId'] = self::getKeyId($_POST);                                                           //找一下主键
        //开始生成查询列表的html代码
        $result = self::codeGeneratorHtml($_POST);
        if($result['state'] !== 200){
            return $result;
        }
        //是否需要新增和修改，1是2否
        if($_POST['insertUpdate'] == 1){
            //开始生成新增修改的html代码
            $result = self::codeGeneratorInsertHtml($_POST);
            if($result['state'] !== 200){
                return $result;
            }
        }
        //开始生成JS文件
        $result = self::codeGeneratorJs($_POST);
        if($result['state'] !== 200){
            return $result;
        }
        //开始生成php控制器的代码
        $result = self::codeGeneratorPhpCtrl($_POST);
        if($result['state'] !== 200){
            return $result;
        }
        //开始生成php模型的代码
        $result = self::codeGeneratorPhpModel($_POST);
        return $result;
    }

    /**
     * 描述：开始生成php模型的代码
     * 作者：Zoro.Zhu
     **/
    public static function codeGeneratorPhpModel(&$post){
        $phpPath = of::config('_of.rootDir') . '/model/tempDemo.php';                                //模板PHP模型代码路径
        $phpStr = file_get_contents($phpPath);                                                              //获取html代码
        $newPath = of::config('_of.rootDir') . "/model/{$post['fromNameNew']}.php";                     //新代码的路径
        $modelData = self::getPhpModelStr($post);
        $phpStr = str_replace("{{queryColumn}}", $modelData['queryColumn'], $phpStr);                   //查询字段替换
        $phpStr = str_replace("//{{search}}", $modelData['search'], $phpStr);                           //搜索的代码替换
        $phpStr = str_replace("{{update}}", $modelData['update'], $phpStr);                             //修改语句代码替换
        $phpStr = str_replace("{{insertColumn}}", $modelData['insertColumn'], $phpStr);                 //新增字段替换
        $phpStr = str_replace("{{insertData}}", $modelData['insertData'], $phpStr);                     //新增数据替换
        $phpStr = str_replace("{{keyId}}", $post['keyId'], $phpStr);                                    //主键替换
        $phpStr = str_replace("temp_demo", $post['fromName'], $phpStr);                                 //表名替换
        $phpStr = str_replace("tempDemo", $post['fromNameNew'], $phpStr);                             //代码关键词替换
        $phpStr = str_replace("Zoro.Zhu", $post['author'], $phpStr);                                  //作者替换
        return self::writeFill($newPath, $phpStr);

    }

    /**
     * 描述：获取php模型的代码
     * 作者：Zoro.Zhu
     **/
    public static function getPhpModelStr(&$post){
        $model = array(
            'queryColumn' => '',
            'search' => '',
            'update' => '',
            'insertColumn' => '',
            'insertData' => '',
        );
        foreach($post['query'] as $key => $val){
            $model['queryColumn'] .= " `{$key}`,";                                                  //查询的sql字段
            if($key != $post['keyId']){
                $model['insertColumn'] .= " `{$key}`,";                                                  //新增的sql字段 之所以和查询的字段分开，是为了后面优化的思路
                $model['insertData'] .= ' \'{$data[\'' . $key . '\']}\',';
            }
            if($val !== ''){                                                                        //需要查询，生成查询条件语句
                switch ($val){
                    case 'LIKE':
                        $model['search'] .= '
        $sql .= !empty($params[\'search\'][\'' . $key . '\']) ? " AND `' . $key . '` LIKE \'%{$params[\'search\'][\'' . $key . '\']}%\' " : "";';
                        break;
                    case '>=+<=':
                        $model['search'] .= '
        $sql .= !empty($params[\'search\'][\'' . $key . 'Start\']) ? " AND `' . $key . '` >= \'{$params[\'search\'][\'' . $key . 'Start\']}\' " : "";';
                        $model['search'] .= '
        $sql .= !empty($params[\'search\'][\'' . $key . 'End\']) ? " AND `' . $key . '` <= \'{$params[\'search\'][\'' . $key . 'End\']}\' " : "";';
                        break;
                    default:
                        $model['search'] .= '
        $sql .= !empty($params[\'search\'][\'' . $key . '\']) ? " AND `' . $key . '` = \'{$params[\'search\'][\'' . $key . '\']}\' " : "";';
                }
            }
            if($key !== $post['keyId']){                                                        //生成修改语句中set的那部分
                $model['update'] .= '
            `' . $key . '` = \'{$data[\'' . $key . '\']}\',';
            }
        }
        $model['queryColumn'] = trim($model['queryColumn'], ',');
        $model['insertColumn'] = trim($model['insertColumn'], ',');
        $model['insertData'] = trim($model['insertData'], ',');
        $model['update'] = trim($model['update'], ',');
        return $model;
    }

    /**
     * 描述：开始生成php控制器的代码
     * 作者：Zoro.Zhu
     **/
    public static function codeGeneratorPhpCtrl(&$post){
        $phpPath = of::config('_of.rootDir') . '/ctrl/tempDemo.php';                                //模板PHP控制器代码路径
        $phpStr = file_get_contents($phpPath);                                                              //获取html代码
        $newPath = of::config('_of.rootDir') . "/ctrl/{$post['fromNameNew']}.php";                     //新代码的路径
        $phpColumn = self::getPhpColumn($post);
        $phpStr = str_replace("'{{exhibition}}',", $phpColumn['exhibition'], $phpStr);                 //列表展示字段替换
        $phpStr = str_replace("'{{insertColumn}}';", $phpColumn['insertColumn'], $phpStr);             //新增和修改的查询字段替换
        $phpStr = str_replace('"`csvTitle`"', $phpColumn['csvTitle'], $phpStr);             //csv标题字段替换
        $phpStr = str_replace('"`csvInfo`"', $phpColumn['csvInfo'], $phpStr);             //csv内容字段替换
        $phpStr = str_replace("tempDemo", $post['fromNameNew'], $phpStr);                              //代码关键词替换
        $phpStr = str_replace("{{keyId}}", $post['keyId'], $phpStr);                                    //主键替换
        $phpStr = str_replace("{{title}}", $post['tableName'], $phpStr);                            //功能名称替换
        $phpStr = str_replace("Zoro.Zhu", $post['author'], $phpStr);                                  //作者替换
        return self::writeFill($newPath, $phpStr);
    }

    /**
     * 描述：获取php列表展示的代码
     * 作者：Zoro.Zhu
     **/
    public static function getPhpColumn(&$post){
        $data = array(
            'exhibition' => '',                                                                         //展示列表的字段
            'insertColumn' => '',                                                                       //新增和修改的查询字段
            'csvTitle' => '',                                                                           //导出csv的标题
            'csvInfo' => '',                                                                            //导出csv的数据类容
        );
        foreach($post['exhibition'] as $key => $val){
            $data['insertColumn'] .= '
                $this->view->' . $key . ' = $tempDemo[0][\'' . $key . '\'];';
            //等于2代表不展示
            if($val == 2){
                continue;
            }
            //1是需要排序，2是不用排序
            if($post['sort'][$key] == 1){
                $data['exhibition'] .= "
            '{$post['comment'][$key]}' => array(
                '_attr' => array(
                    'body' => '{`{$key}`}',
                    'sort' => '{$key}'
                )
            ),";
            }else{
                $data['exhibition'] .= "
            '{$post['comment'][$key]}' => '{`{$key}`}',";
            }
            $data['csvTitle'] .= "'{$post['comment'][$key]}',";
            $data['csvInfo'] .= '$row[\'' . $key . '\'],';
        }
        //是否需要修改功能
        if($post['insertUpdate'] == 1){
            $data['exhibition'] .= '
            \'操作\'=> "<button class=\"btn btn-oper btn-danger\" type=\"button\" onclick=\"tempDemoObj.tempDemoUpInfo(\'{`{{keyId}}`}\');\">
                <span class=\"fa fa-plus\"></span>修改
            </button>",';
        }
        $data['insertColumn'] = trim($data['insertColumn'], ',');
        return $data;
    }

    /**
     * 描述：生成html列表的代码
     * 作者：Zoro.Zhu
     **/
    public static function codeGeneratorHtml(&$post){
        $htmlPath = of::config('_of.rootDir') . '/view/html/tempDemo.html';                     //模板HTML代码路径
        $htmlStr = file_get_contents($htmlPath);                                                        //获取html代码
        $newPath = of::config('_of.rootDir') . "/view/html/{$post['fromNameNew']}.html";           //新代码的路径
        $insertStr = self::generatorInsert($post);
        $htmlStr = str_replace("{{insert}}", $insertStr, $htmlStr);                               //代码关键词替换
        $queryStr = self::generatorQuery($post);
        $htmlStr = str_replace("{{query}}", $queryStr, $htmlStr);                               //代码关键词替换
        $htmlStr = str_replace("tempDemo", $post['fromNameNew'], $htmlStr);                        //代码关键词替换
        $htmlStr = str_replace("{{title}}", $post['tableName'], $htmlStr);                      //代码关键词替换
        return self::writeFill($newPath, $htmlStr);
    }


    /**
     * 描述：获取新增按钮的代码
     * 作者：Zoro.Zhu
     **/
    public static function generatorInsert(&$post){
        $str = "";
        if($post['insertUpdate'] == 1){
            $str .= "
                        <input class=\"btn btn-warning\" type=\"button\" onclick=\"tempDemoObj.tempDemoUpInfo()\" value=\"新增\">";
        }
        return $str;
    }

    /**
     * 描述：生成html新增修改的代码
     * 作者：Zoro.Zhu
     **/
    public static function codeGeneratorInsertHtml(&$post){
        $htmlPath = of::config('_of.rootDir') . '/view/html/tempDemoUpInfo.html';               //模板HTML代码路径
        $htmlStr = file_get_contents($htmlPath);                                                        //获取html代码
        $newPath = of::config('_of.rootDir') . "/view/html/{$post['fromNameNew']}UpInfo.html";           //新代码的路径
        $htmlStr = str_replace("tempDemo", $post['fromNameNew'], $htmlStr);                        //代码关键词替换
        $inputStr = self::generatorInput($post);
        $htmlStr = str_replace("{{input}}", $inputStr, $htmlStr);                               //代码关键词替换
        return self::writeFill($newPath, $htmlStr);
    }

    /**
     * 描述：生成js的代码
     * 作者：Zoro.Zhu
     **/
    public static function codeGeneratorJs(&$post){
        $jsPath = of::config('_of.rootDir') . '/view/js/tempDemo.js';                           //模板JS代码路径
        $jsStr = file_get_contents($jsPath);                                                          //获取js代码
        $newPath = of::config('_of.rootDir') . "/view/js/{$post['fromNameNew']}.js";               //新代码的路径
        $search = self::getJsSearch($post);
        $jsStr = str_replace("{{search}}", $search['query'], $jsStr);                                 //查询条件错位符替换
        $jsStr = str_replace("{{export}}", $search['export'], $jsStr);                                 //导出数据错位符替换
        $mustFill = self::getJsMustFill($post);
        $jsStr = str_replace("{{mustFill}}", $mustFill, $jsStr);                                 //代码标题错位符替换
        $jsStr = str_replace("tempDemo", $post['fromNameNew'], $jsStr);                           //代码关键词替换
        $jsStr = str_replace("{{keyId}}", $post['keyId'], $jsStr);                                  //主键替换
        $jsStr = str_replace("{{title}}", $post['tableName'], $jsStr);                          //代码标题错位符替换
        $jsStr = str_replace("Zoro.Zhu", $post['author'], $jsStr);                                  //作者替换
        return self::writeFill($newPath, $jsStr);
    }


    /**
     * 描述：获取js搜索和导出的代码
     * 作者：Zoro.Zhu
     **/
    public static function getJsSearch($post){
        $data = array(
            'query' => '',
            'export' => ''
        );
        foreach ($post['query'] as $key => $val) {
            if ($val === '') {
                continue;
            }
            if($val == '>=+<='){
                $data['query'] .= "
            {$key}Start: $(\"#{$key}Start\").val(),
            {$key}End: $(\"#{$key}End\").val(),";
                $data['export'] .= " + '&{$key}Start=' + {$key}Start  + '&{$key}End=' + {$key}End";
            }else{
                $data['query'] .= "
            {$key}: $(\"#{$key}\").val(),";
                $data['export'] .= " + '&{$key}=' + args.{$key}";
            }
        }
        return $data;
    }

    /**
     * 描述：获取js必填验证的代码
     * 作者：Zoro.Zhu
     **/
    public static function getJsMustFill($post){
        $str = '';
        foreach ($post['mustFill'] as $key => $val) {
            if ($val == '2') {
                continue;
            }
            $str .= "
                            {$key}: '{$post['comment'][$key]}',";
        }
        return $str;
    }

    /**
     * 描述：生成新增修改输入框的代码
     * 作者：Zoro.Zhu
     **/
    public static function generatorInput(&$post){
        $str = '';
        foreach($post['comment'] as $key =>$val){
            //主键只读，不能修改
            if($post['key'][$key] == 'PRI'){
                $readonly = '_="empty($this->' . $key . ') ? "" : "readonly"';
            }else{
                $readonly = '';
            }
            switch ($post['type'][$key]) {
                case 'int':
                    $typeClass = 'type="int" class="form-control jsSearchInput"';
                    break;
                case 'datetime':
                    $typeClass = 'type="text" class="form-control wDateInput readonly-bg" readonly="readonly"';
                    break;
                default :
                    $typeClass = 'type="text" class="form-control jsSearchInput"';
            }
            $str .= '
            <div class="form-group">
                <label class="col-md-3 control-label">' . $val . ':</label>
                <div class="col-md-9 padding-left-0">
                    <input ' . $typeClass . ' name="' . $key . '" _value="empty($this->' . $key . ') ? \'\' : $this->' . $key . '"  ' . $readonly . '>
                </div>
            </div>';
        }
        return $str;
    }

    /**
     * 描述：生成查询的代码
     * 作者：Zoro.Zhu
     **/
    public static function generatorQuery(&$post){
        $str = '';
        foreach ($post['query'] as $key => $val){
            if($val === ''){
                continue;
            }
            switch ($post['type'][$key]){
                case 'int':
                    if($val == '>=+<='){
                        $str .= "
                <div class=\"col-sm-4 col-md-4 col-lg-3 add-space\">
                    <div class=\"input-group input-group-sm\">
                        <span class=\"input-group-addon\">{$post['comment'][$key]}</span>
                        <input type=\"int\" class=\"form-control jsSearchInput\" id=\"{$key}Start\" readonly=\"readonly\"/>
                        <span class=\"input-group-addon\">~</span>
                        <input type=\"int\" class=\"form-control jsSearchInput\" id=\"{$key}End\" readonly=\"readonly\"/>
                    </div>
                </div>";
                    }else{
                        $str .= "
                <div class=\"col-sm-4 col-md-4 col-lg-3 add-space\">
                    <div class=\"input-group input-group-sm \">
                        <span class=\"input-group-addon\">{$post['comment'][$key]}</span>
                        <input class=\"form-control jsSearchInput\" id=\"{$key}\" type=\"int\"/>
                    </div>
                </div>";
                    }
                    break;
                case 'datetime':
                    $str .= "
                <div class=\"col-sm-4 col-md-4 col-lg-3 add-space\">
                    <div class=\"input-group input-group-sm\">
                        <span class=\"input-group-addon\">{$post['comment'][$key]}</span>
                        <input type=\"text\" class=\"form-control wDateInput readonly-bg\" readonly=\"readonly\" id=\"{$key}Start\" />
                        <span class=\"input-group-addon\">~</span>
                        <input type=\"text\" class=\"form-control wDateInput readonly-bg\" readonly=\"readonly\" id=\"{$key}End\" />
                    </div>
                </div>";
                    break;
                default :
                    $str .= "
                <div class=\"col-sm-4 col-md-4 col-lg-3 add-space\">
                    <div class=\"input-group input-group-sm \">
                        <span class=\"input-group-addon\">{$post['comment'][$key]}</span>
                        <input class=\"form-control jsSearchInput\" id=\"{$key}\" type=\"text\"/>
                    </div>
                </div>";
            }
        }
        return $str;
    }

    /**
     * 描述：转换一下表名，将下划线处理掉
     * 参数：fromName : 未处理之前的表名
     * 返回值：处理后的表名
     * 作者：Zoro.Zhu
     **/
    public static function fromNameChange($fromName){
        $fromName = explode('_', $fromName);
        $newFromName = '';
        foreach($fromName as $key => $val){
            $newFromName .= $key === 0 ? $val : ucfirst($val);
        }
        return $newFromName;
    }

    /**
     * 描述：整理出主键
     * 作者：Zoro.Zhu
     **/
    public static function getKeyId($post){
        $keyId = "";
        foreach($post['key'] as $key => $val){
            if($val != 'PRI'){
                continue;
            }
            if($keyId === ''){
                $keyId = $key;
                //TODO 多主键如何处理？
            }else{

            }
        }
        return $keyId;
    }

    /**
     * 描述：创建新文件
     * 参数1：path ：文件地址
     * 参数2：str ：文件内容
     * 作者：Zoro.Zhu
     **/
    public static function writeFill($path, $str){
        if(file_exists($path)){
            return array('state' => 400, 'info' => '文件已存在');
        }
        $myfile = fopen($path, "w") or die("Unable to open file!");
        fwrite($myfile, $str);
        fclose($myfile);
        return array('state' => 200, 'info' => '创建成功');
    }



}
return true;